import { Component, OnInit, ViewChild, ElementRef, Input, Output, EventEmitter } from '@angular/core';
import * as go from '../../../assets/gojs/go-debug';

@Component({
  selector: 'app-custom-diagram-editor',
  templateUrl: './custom-diagram-editor.component.html',
  styleUrls: ['./custom-diagram-editor.component.css']
})
export class CustomDiagramEditorComponent implements OnInit {
  private diagram: go.Diagram = new go.Diagram();
  private palette: go.Palette = new go.Palette();

  @ViewChild('diagramDiv')
  private diagramRef: ElementRef;

  @ViewChild('paletteDiv')
  private paletteRef: ElementRef;

  @Input()
  get model(): go.Model { return this.diagram.model; }
  set model(val: go.Model) { this.diagram.model = val; }

  @Output()
  nodeSelected = new EventEmitter<go.Node | null>();

  @Output()
  modelChanged = new EventEmitter<go.ChangedEvent>();

  constructor() {
    const $ = go.GraphObject.make;
    this.diagram = new go.Diagram();
    this.diagram.initialContentAlignment = go.Spot.Center;
    this.diagram.allowDrop = true;  // 必要，用来从调色板托动到流程图上
    this.diagram.undoManager.isEnabled = true;
    this.diagram.addDiagramListener('ChangedSelection', // 绑定选择改变事件，发送消息
      e => {
        const node = e.diagram.selection.first();
        this.nodeSelected.emit(node instanceof go.Node ? node : null);
      });
    this.diagram.addModelChangedListener(e => e.isTransactionFinished && this.modelChanged.emit(e));  // 绑定模型改变消息

    /** 节点模板 */
    this.diagram.nodeTemplate =
      $(go.Node, 'Auto',
        new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify), // 绑定位置属性到 loc
        /** 形状 */
        $(go.Shape,
          {
            fill: 'white',  // 填充颜色
            strokeWidth: 0, // 边框粗细
            portId: '', //
            cursor: 'pointer',  // 鼠标样式
            // 允许多种连线
            fromLinkable: true, // 允许作为连线起始
            toLinkable: true, // 允许作为连线终点
            fromLinkableSelfNode: false, // 允许从自己连到自己
            toLinkableSelfNode: false, // 允许从自己连到自己
            fromLinkableDuplicates: false, // 允许作为多条线的起点
            toLinkableDuplicates: false  // 允许作为多条线的终点
          },
          new go.Binding('fill', 'color')), // 绑定颜色
        /** 文字 */
        $(go.TextBlock,
          { margin: 8, editable: true },
          new go.Binding('text').makeTwoWay())  // 双向绑定文字属性
      );

    /** 连线模板 */
    this.diagram.linkTemplate =
      $(go.Link,
        // 允许重连
        { relinkableFrom: true, relinkableTo: true, reshapable: true },
        {
          routing: go.Link.AvoidsNodes,
          curve: go.Link.JumpOver,
          corner: 5,
          toShortLength: 4
        },
        new go.Binding('points').makeTwoWay(),
        $(go.Shape, { isPanelMain: true, strokeWidth: 2 }),  // 起点形状
        $(go.Shape, { toArrow: 'Standard', stroke: null }),  // 终点形状 // OpenTriangle
        /*$(go.Panel, 'Auto',
          new go.Binding('visible', 'isSelected').ofObject(),
          $(go.Shape, 'RoundedRectangle',  // 线上的形状
            { fill: '#F8F8F8', stroke: null }),
          $(go.TextBlock,
            {
              textAlign: 'center',
              font: '10pt helvetica, arial, sans-serif',
              stroke: '#919191',
              margin: 2,
              minSize: new go.Size(10, NaN),
              editable: true
            },
            new go.Binding('text').makeTwoWay())
        )*/
      );

    this.palette = new go.Palette();
    this.palette.nodeTemplateMap = this.diagram.nodeTemplateMap;

    // 初始化调色板
    this.palette.model.nodeDataArray =
      [
        { text: '开始', color: 'lightblue' },
        { text: '流程节点', color: 'orange' },
        { text: '结束', color: 'lightgreen' },
        { text: '连接线', color: 'pink' }
      ];
  }

  ngOnInit() {
    this.diagram.div = this.diagramRef.nativeElement;
    this.palette.div = this.paletteRef.nativeElement;
  }
}
